package com.wrox;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

@WebServlet(
		name = "ticketServlet",
		urlPatterns = {"/tickets"},
		loadOnStartup = 1
		)
//@@MultipartConfig 将告诉Web容器为该Servlet提供文件上传支持
@MultipartConfig(
		fileSizeThreshold = 5_242_880,//5M 小于5M的上传文件将保存在内存中，直到请求完成，然后由垃圾回收器回收，对于超过5M的文件，容器将把该文件保存在location指向的目录中，在请求完成后，容器将从磁盘中删除该文件
		maxFileSize = 20_971_520L,//20M  禁止上传大小超过20M的文件
		maxRequestSize = 41_943_040L //40M， 禁止大小超过40M的请求
		//location= .....
		)
public class TicketServlet extends HttpServlet{
	private volatile int TICKET_ID_SEQUENCE = 1;
	private Map<Integer, Ticket> ticketDatabase = new LinkedHashMap<Integer, Ticket>();
	public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{
		String action = request.getParameter("action");
		if(request.getSession().getAttribute("username") == null){
			response.sendRedirect("login");
			return;
		}
		if(action == null){
			action = "list";
		}
		switch(action){
		case "create":
			this.showTicketForm(request,response);
			break;
		case "view":
			this.viewTicket(request,response);
			break;
		case "download":
			this.downloadAttachment(request,response);
			break;
		default:
			this.listTickets(request,response);
			break;
		}
	}
	
	public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{
		String action = request.getParameter("action");
		if(request.getSession().getAttribute("username") == null){
			response.sendRedirect("login");
			return;
		}
		if(action == null){
			action = "list";
		}
		switch (action) {
		case "create":
			this.createTicket(request,response);
			break;
		case "download":

		default:
			response.sendRedirect("tickets");
			break;
		}
	}
	private void createTicket(HttpServletRequest request,
			HttpServletResponse response) throws IllegalStateException, IOException, ServletException {
		Ticket ticket = new Ticket();
		ticket.setCustomerName((String) request.getSession().getAttribute("username"));
		ticket.setSubject(request.getParameter("subject"));
		ticket.setBody(request.getParameter("body"));
		
		Part filePart = request.getPart("file1");
		if(filePart != null){
			Attachment attachment = this.processAttachment(filePart);
			if(attachment != null){
				ticket.addAttachment(attachment);
			}
		}
		int id;
		synchronized (this) {
			id = this.TICKET_ID_SEQUENCE ++;
			this.ticketDatabase.put(id, ticket);
		}
		response.sendRedirect("tickets?action=ciew&ticketId=" + id);
	}

	private Attachment processAttachment(Part filePart) throws IOException {
		InputStream inputStream = filePart.getInputStream();
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		int read;
		final byte[] bytes = new byte[1024];
		while((read = inputStream.read(bytes)) != -1){
			outputStream.write(bytes,0,read);
		}
		Attachment attachment = new Attachment();
		attachment.setName(filePart.getName());
		attachment.setContents(outputStream.toByteArray());
		return attachment;
	}

	private void listTickets(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
		request.setAttribute("ticketDatabase", this.ticketDatabase);
		request.getRequestDispatcher("/WEB-INF/jsp/view/listTickets.jsp").forward(request, response);
	}
	private void writeFooter(PrintWriter writer) {
		writer.append("    </body>\r\n").append("</html>\r\n");
	}

	private PrintWriter writeHeader(HttpServletResponse response) throws IOException {
		response.setContentType("text/html");
		response.setCharacterEncoding("UTF-8");
		PrintWriter writer = response.getWriter();
		writer.append("<!DOCTYPE html>\r\n")
			.append("<html>\r\n")
			.append("    <head>\r\n")
			.append("        <title>Customer Support</title>\r\n")
			.append("    </head>\r\n")
			.append("    <body>\r\n");
		return writer;
		
	}

	private void downloadAttachment(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		String idString = request.getParameter("ticketId");
		Ticket ticket = this.getTicket(idString,response);
		if(ticket == null){
			return;
		}
		String name = request.getParameter("attachment");
		if(name == null){
			response.sendRedirect("tickets?action=view&ticketId=" + idString);
			return;
		}
		Attachment attachment = ticket.getAttachment(name);
		if(attachment == null){
			response.sendRedirect("tickets?action=view&ticketId=" + idString);
			return;
		}
		response.setHeader("Content-Disposition", "attachment;filename=" + attachment.getName());
		response.setContentType("application/octet-stream");
		
		ServletOutputStream stream = response.getOutputStream();
		stream.write(attachment.getContents());
	}
	private Ticket getTicket(String idString, HttpServletResponse response) throws IOException {
		if(idString == null || idString.length() == 0){
			response.sendRedirect("tickets");
			return null;
		}
		try {
			Ticket ticket = this.ticketDatabase.get(Integer.parseInt(idString));
			if(ticket == null){
				response.sendRedirect("tickets");
				return null;
			}
			return ticket;
		} catch (Exception e) {
			response.sendRedirect("tickets");
			return null;
		}
	}

	private void viewTicket(HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		String id = request.getParameter("ticketId");
		Ticket ticket = this.getTicket(id, response);
		if(ticket == null){
			return;
		}
		request.setAttribute("ticketId", id);
		request.setAttribute("ticket", ticket);
		
		request.getRequestDispatcher("/WEB-INF/jsp/view/viewTicket.jsp").forward(request, response);
	}
	private void showTicketForm(HttpServletRequest requst,HttpServletResponse response) throws IOException, ServletException {
		requst.getRequestDispatcher("/WEB-INF/jsp/view/ticketForm.jsp").forward(requst, response);
	}

}
